package com.xmhmyh.generalframework.common;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmhmyh.generalframework.common.constants.Constants;
import com.xmhmyh.generalframework.common.entity.Condition;
import com.xmhmyh.generalframework.common.entity.DataGridRequest;
import com.xmhmyh.generalframework.common.enums.Operator;
import com.xmhmyh.generalframework.common.enums.ResponseCode;
import com.xmhmyh.generalframework.common.enums.SortOrder;
import com.xmhmyh.generalframework.framework.exceptions.ManageExceptions;
import com.xmhmyh.generalframework.framework.redis.RedisServiceImpl;
import com.xmhmyh.generalframework.framework.uid.UidGenerator;
import com.xmhmyh.generalframework.framework.yusngen.YuSnGenUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: 于丁
 * @Description:
 * @DateTime: 2020/7/24 9:14 上午
 * @Params:
 * @Return
 */
public abstract class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M, T> implements BaseIService<T> {
    @Autowired
    protected RedisServiceImpl redisService;


    @Autowired
    protected UidGenerator uidGenerator;

    @Override
    public T getNotNullById(Long id) {
        T t = getById(id);
        if (t == null) {
            throw new ManageExceptions(ResponseCode.ENTITY_NOT_FIND);
        }
        return t;
    }

    @Override
    public T getNotNullById(Long id, ResponseCode responseCode) {
        T t = getById(id);
        if (t == null) {
            throw new ManageExceptions(responseCode);
        }
        return t;
    }

    @Override
    public IPage<T> paginate(DataGridRequest dataGridReq) {
        Page<T> page = new Page<T>(dataGridReq.getPageNo(), dataGridReq.getPageSize());
        QueryWrapper<T> queryWrapper = convertDataGridRequest(dataGridReq);
        IPage<T> iPage = baseMapper.selectPage(page, queryWrapper);
        return iPage;
    }

    public QueryWrapper<T> convertDataGridRequest(DataGridRequest dataGridReq) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        List<Condition> conditions = dataGridReq.getConditions();
        if (CollectionUtils.isNotEmpty(conditions)) {
            for (Condition condition : conditions) {
                String operator = condition.getOperator();
                List<String> values = condition.getValues();
                String field = condition.getField();
                String column = StringUtils.camelToUnderline(field);
                if (operator.equalsIgnoreCase(Operator.EQ.getLabel())) {
                    queryWrapper.eq(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.NE.getLabel())) {
                    queryWrapper.ne(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.IN.getLabel())) {
                    queryWrapper.in(column, values);
                } else if (operator.equalsIgnoreCase(Operator.NI.getLabel())) {
                    queryWrapper.notIn(column, values);
                } else if (operator.equalsIgnoreCase(Operator.IS.getLabel())) {
                    queryWrapper.isNull(column);
                } else if (operator.equalsIgnoreCase(Operator.NS.getLabel())) {
                    queryWrapper.isNotNull(column);
                } else if (operator.equalsIgnoreCase(Operator.LK.getLabel())) {
                    queryWrapper.like(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.NK.getLabel())) {
                    queryWrapper.notLike(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.LE.getLabel())) {
                    queryWrapper.le(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.GE.getLabel())) {
                    queryWrapper.ge(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.GT.getLabel())) {
                    queryWrapper.gt(column, values.get(0));
                } else if (operator.equalsIgnoreCase(Operator.LT.getLabel())) {
                    queryWrapper.lt(column, values.get(0));
                }
            }
        }
        Map<String, LinkedHashMap<String, String>> orderMap = dataGridReq.getOrderClauseMap();
        LinkedHashMap<String, String> sortColumnMap = orderMap.get(Constants.ORDERMAP);
        if (MapUtils.isNotEmpty(sortColumnMap)) {
            for (Map.Entry<String, String> entry : sortColumnMap.entrySet()) {
                String column = StringUtils.camelToUnderline(entry.getKey());
                SortOrder sortOrder = SortOrder.valueOf(entry.getValue().toUpperCase());
                if (SortOrder.ASC.name().equals(sortOrder.name())) {
                    queryWrapper.orderByAsc(column);
                } else {
                    queryWrapper.orderByDesc(column);
                }
            }
        }
        return queryWrapper;
    }
}
